package com.wn.framework.decoration

import android.R
import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.View
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView

/**
 * @Author: wn
 * @Date: 2025/4/17 16:55
 * @Description: 设置分割线 Divider
 */
class DividerItemDecoration(context: Context, orientation: Int) : RecyclerView.ItemDecoration() {
  /**
   * @return the [Drawable] for this divider.
   */
  var drawable: Drawable?
    private set
  private var mDrawLastPositionDivider = true

  /**
   * Current orientation. Either [.HORIZONTAL] or [.VERTICAL].
   */
  private var mOrientation = 0
  private val mBounds = Rect()

  /**
   * Sets the orientation for this divider. This should be called if
   * [RecyclerView.LayoutManager] changes orientation.
   *
   * @param orientation [.HORIZONTAL] or [.VERTICAL]
   */
  fun setOrientation(orientation: Int) {
    require(!(orientation != HORIZONTAL && orientation != VERTICAL)) { "Invalid orientation. It should be either HORIZONTAL or VERTICAL" }
    mOrientation = orientation
  }

  /**
   * Sets the [Drawable] for this divider.
   *
   * @param drawable Drawable that should be used as a divider.
   */
  fun setDrawable(drawable: Drawable) {
    requireNotNull(drawable) { "Drawable cannot be null." }
    this.drawable = drawable
  }

  fun isDrawLastPositionDivider(isDraw: Boolean) {
    mDrawLastPositionDivider = isDraw
  }

  override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
    if (parent.layoutManager == null || drawable == null) {
      return
    }
    if (mOrientation == VERTICAL) {
      drawVertical(c, parent, state)
    } else {
      drawHorizontal(c, parent, state)
    }
  }

  private fun drawVertical(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
    canvas.save()
    val left: Int
    val right: Int
    if (parent.clipToPadding) {
      left = parent.paddingLeft
      right = parent.width - parent.paddingRight
      canvas.clipRect(
        left, parent.paddingTop, right,
        parent.height - parent.paddingBottom
      )
    } else {
      left = 0
      right = parent.width
    }
    val childCount = parent.childCount
    val lastPosition = state.itemCount - 1
    for (i in 0 until childCount) {
      val child = parent.getChildAt(i)
      val childRealPosition = parent.getChildAdapterPosition(child)
      if (mDrawLastPositionDivider || childRealPosition < lastPosition) {
        parent.getDecoratedBoundsWithMargins(child, mBounds)
        val bottom = mBounds.bottom + Math.round(child.translationY)
        val top = bottom - drawable!!.intrinsicHeight
        drawable!!.setBounds(left, top, right, bottom)
        drawable!!.draw(canvas)
      }
    }
    canvas.restore()
  }

  private fun drawHorizontal(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
    canvas.save()
    val top: Int
    val bottom: Int
    if (parent.clipToPadding) {
      top = parent.paddingTop
      bottom = parent.height - parent.paddingBottom
      canvas.clipRect(
        parent.paddingLeft, top,
        parent.width - parent.paddingRight, bottom
      )
    } else {
      top = 0
      bottom = parent.height
    }
    val childCount = parent.childCount
    val lastPosition = state.itemCount - 1
    for (i in 0 until childCount) {
      val child = parent.getChildAt(i)
      val childRealPosition = parent.getChildAdapterPosition(child)
      if (mDrawLastPositionDivider || childRealPosition < lastPosition) {
        parent.layoutManager!!.getDecoratedBoundsWithMargins(child, mBounds)
        val right = mBounds.right + Math.round(child.translationX)
        val left = right - drawable!!.intrinsicWidth
        drawable!!.setBounds(left, top, right, bottom)
        drawable!!.draw(canvas)
      }
    }
    canvas.restore()
  }

  override fun getItemOffsets(
    outRect: Rect, view: View, parent: RecyclerView,
    state: RecyclerView.State,
  ) {
    if (drawable == null) {
      outRect[0, 0, 0] = 0
      return
    }
    if (mOrientation == VERTICAL) {
      outRect[0, 0, 0] = drawable!!.intrinsicHeight
    } else {
      outRect[0, 0, drawable!!.intrinsicWidth] = 0
    }
  }

  companion object {
    const val HORIZONTAL = LinearLayout.HORIZONTAL
    const val VERTICAL = LinearLayout.VERTICAL
    private const val TAG = "DividerItem"
    private val ATTRS = intArrayOf(R.attr.listDivider)
  }

  /**
   * Creates a divider [RecyclerView.ItemDecoration] that can be used with a
   * [LinearLayoutManager].
   *
   * @param context     Current context, it will be used to access resources.
   * @param orientation Divider orientation. Should be [.HORIZONTAL] or [.VERTICAL].
   */
  init {
    val a = context.obtainStyledAttributes(ATTRS)
    drawable = a.getDrawable(0)
    if (drawable == null) {
      Log.w(
        TAG, "@android:attr/listDivider was not set in the theme used for this "
                + "DividerItemDecoration. Please set that attribute all call setDrawable()"
      )
    }
    a.recycle()
    setOrientation(orientation)
  }
}